 function EventObject (row,index,size,gridid)
 {
	 
	this.RowIndex=index;
	this.RowCount=size;
	this.GridKey=gridid;
	
	this.EventCount=row["EventCount"];
	this.EventName=row["EventName"];
	this.EventName = this.EventName.replace ('&pos;', "'");
	this.RoomName=row["RoomName"];
	this.SetupStartTime=row["SetupStartTime"];
	this.SetupEndTime=row["SetupEndTime"];
	this.EventStartTime=row["EventStartTime"];
	this.EventEndTime=row["EventEndTime"];
	this.EventDate=row["EventDate"];
	this.CustomDate=row["CustomDate"];
	this.RecurseEndDate=row["RecurseEndDate"] || row["EventDate"];
	this.Duration=row["Duration"];
	this.FullName=row["FullName"];
	this.Description=row["Description"] || '';
	this.Comments=row["Comments"] || '';
	this.CreateDate=row["CreateDate"];
	this.CreateLogin=row["CreateLogin"];
	this.ApproveDate=row["ApproveDate"];
	this.ApproveLogin=row["ApproveLogin"];
	try
	{ var x=new Date (dateUS(this.CustomDate) + ' ' + this.EventStartTime);
	  this.ActualDateandTime=x.getTime();
	} catch (ex) { }
	this.Display=row["Display"];
	this.Recurring=row["Recurring"];
	this.Attendees=row["Attendees"];
	this.RecurseType=row["RecurseType"]||'-1';
	this.RecurseUnit=row["RecurseUnit"];
	this.type=row["type"]||'-1';
	this.RoomIdent=row["RoomIdent"];
	this.ID=row["ID"];
	this.RoomID=row["RoomID"];
	this.Featured=row["Featured"] || '0';
	this.Featured = parseInt (this.Featured);
	// collections
	this.CustomProperties=[];
	this.CustomDates=[];
	this.EventComments=[];
	this.EventCategories=[];
	this.EventCalendars=[];
	this.ConflictDates=[];
	this.Conflicts=[];
	this.Attachments=[];
	this.Rooms=[];
	
	// flags
	this.DateListVisible=false;
	this.RoomListVisible=false;
	this.PropertiesListVisible=true;
	this.CategoryListVisible=true;
	this.CalendarListVisible=true;
	this.AttachmenListVisible=true;
	this.DescriptionVisible=false;
	this.OptionListVisible=false;
	this.InvoiceDisplayDates=0;
	this.ConflictError=0;
	this.SelectedComment=-1;
	this.ROW=row;
	
	this.cdata = function (name, value)
	{
	    return Factory.write ( { 'template' : 'cdata', 'name' : name, 'value' : value } );
	}
	
	this.remove = function ()
	{
		DeleteEvent (this.ID)  ;
	}  
	
	this.scope = function ()
	{
		return Calendar.scope (this.EventDate, this.RecurseEndDate, this.RecurseType, this.RecurseUnit);
	}
	
	this.load = function ()
	{
	}  
	
	this.LaunchAttachmentWindow = function ()
	{
		var htm='<link rel="stylesheet" href="/101/ebp6/style.css"/> ';
		htm+='<body style="padding:4px;border:solid 1px #ffffff" bgcolor="#ffffff">';
		htm+='<img src="/webservices/images/poweredby.gif"><hr noshade size="1">';
		htm+='<form method="post" action="upload.php?event=' + this.ID + '" enctype="multipart/form-data">';
		htm+='Upload an attachment for ' + this.EventName + '<br>';
		htm+='<input type="file" name="file1">'; 
		htm+='<input type="submit" value="Upload File">';
		htm+='</form>';
		htm+='</body>';
		try 
		{ var k=window.open ('about:blank','','width=400,height=150');
		  k.document.write (htm); } 
		catch (ex) { alert (ex.message); }
	}
	//this.LaunchAttachmentWindow ()
	this.MatchDates = function (array)
	{ 
	    var result=new Array ();
	    for (var i in array)
	    {
	        for (var k in this.CustomDates)
	        {
	            if (this.CustomDates[k].value==array[i].value) 
	            {
	                result.push (array[i]);
	            }
	        }
	    }
	    return result;
	}  
	
	
	this.AddComment = function (text)
	{ 
		 var found = new EventComment();
		 found.id=0;
		 found.UserID=window.loggedinuser.id;
		 found.CommentDate=new Date();
		 found.CommentText=text;
		 found.EventFK=window.currentevent.ID
		 found.FullName=window.loggedinuser.name + ' ' + window.loggedinuser.last; 
		 this.EventComments.push (found);
	}
	
	this.AddRoom = function (name, value)
	{
		var found = false;
		for (var x in this.Rooms)
		{
			if (this.Rooms[x].value==value) found=true;
		}
		if (found) alert ('This room is already booked for this event');
		else this.Rooms.push (new RoomObject (name, value));
	}
	
	this.RemoveRoom = function (value)
	{
		var found = [];
		for (var x in this.Rooms)
		{
			if (this.Rooms[x].value!=value) found.push (this.Rooms[x]);
		}
		
		this.Rooms = found;
	}
	  
	this.AddCalendar = function (calendar)
	{ 
		this.EventCalendars.push (calendar);
	}
	
	this.RemoveCalendar = function (value)
	{
		var found = [];
		for (var x in this.EventCalendars)
		{
			if (this.EventCalendars[x].id!=value) found.push (this.EventCalendars[x]);
		} 
		this.EventCalendars = found;
	}
	
	
	this.AddProperty = function (name, value)
	{
		for (var x in this.CustomProperties)
		{
			if (this.CustomProperties[x].name==name) 
			{
				this.CustomProperties[x].value = value;
				return true;
			}
		} 
		var found = new CustomProperty (); 
		found.value=value;
		found.name=name;  
		this.CustomProperties.push (found);
	}
	
	this.RemoveProperty = function (name)
	{
		var found = [];
		for (var x in this.CustomProperties)
		{
			if (this.CustomProperties[x].name!=name) found.push (this.CustomProperties[x]);
		} 
		this.CustomProperties = found;
	}
	
	
	this.AddCategory = function (name, value)
	{
		var found = new EventCategory (); 
		found.id=value;
		found.title=name; 
		this.EventCategories.push (found);
	}
	
	this.AddDate = function (name, value)
	{
		var found = false;
		for (var x in this.CustomDates)
		{
			if (this.CustomDates[x].value==value) found=true;
		}
		
		if (found) alert ('This date is already booked for this event');
		else this.CustomDates.push (new CustomDate (name, value));
	}
	
	this.RemoveDate = function (value)
	{
		var found = [];
		for (var x in this.CustomDates)
		{
			if (this.CustomDates[x].value!=value) found.push (this.CustomDates[x]);
		} 
		this.CustomDates = found;
	}
	
	this.RemoveCategory = function (value)
	{
		var found = [];
		for (var x in this.EventCategories)
		{
			if (this.EventCategories[x].id!=value) found.push (this.EventCategories[x]);
		} 
		this.EventCategories = found;
	}
	
	this.MakeRoomString = function ()
	{
		var found = [];
		for (var x in this.Rooms)
		{ 
			found.push (this.Rooms[x].name);
		}
		found.sort();
		return found.join (', ');
	}
	
	this.SerializeEnvelope = function (node)
	{  
		var markup='';
		markup += '';
		markup += '  <' + node + '>\n';
		markup += '    <recordset>\n[CONTENT]';
		markup += '    </recordset>\n';
		markup += '  </' + node + '>\n'; 
		return markup;
	}
	
	this.afterpresave = function ()
	{ //
		if (this.Conflicts.length==0)
		{
			this.commit ();
			return true;
		}
		this.ConflictError=1;
		DebugEventDetailForm.invoke();
	}
	
	this.resolve = function (index)
	{
		if (index < 0) return false;
		this.commands = new Array (this.commit, this.savenoapprove, this.cancel);
		this.command = this.commands [index];
		this.command();
	}
	
	this.savenoapprove = function ()
	{
		this.cancel ();
		this.ApproveLogin = 0;
		this.commit ();
	}
	
	this.cancel = function ()
	{
		this.ConflictDates=[];
		this.Conflicts=[]; 
		this.ConflictError=0;
		DebugEventDetailForm.invoke();
	}
	
	this.Time2Number = function (data)
	{ 
		var time;
		if (time=/(\d+)\:(\d+)(am|pm)/.exec(data))
		{
			var hour = parseInt (time[1], 10)==12 ? 0 : time[1];
			return parseInt(hour * 3600, 10) + 
					parseInt(time[2] * 60, 10) + 
					parseInt((time[3]=='pm' ? 43200 : 0), 10);
		}
		else
		{
			time = data.split (':');
			var hour = parseInt (time[0], 10)==12 ? 0 : time[0];
			return parseInt(hour * 3600, 10) + 
					parseInt(time[1] * 60, 10) + 
					parseInt(time[2], 10);
		}
		return parseInt (time.replace(/\:/g,''));
	}
	
	this.validate = function ()
	{  
		var error=[],warning=[],times=['SetupStartTime','EventStartTime','EventEndTime','SetupEndTime'];
		var names = EventObject.params();
		if (this.CustomDates.length==0 && this.RecurseType >= 0)
			error.push ('&#167; The event is set as recurring but has no dates assigned');
		if (!isDate (this.RecurseEndDate) && this.RecurseType >= 0)
			error.push ('&#167; The event is set as recurring but the End Date ('+this.RecurseEndDate+') is blank or invalid');
		if (this.Rooms.length==0) 
			error.push ('&#167; No rooms have been defined for the event'); 		
		
		var tb, te
		for (var x=1;x<times.length;x++)
		{
			for (var y=x-1;y>=0;y--)
			{
				tb = this.Time2Number ( this[ times[y] ] );
				te = this.Time2Number ( this[ times[x] ] );
				if (tb > te)
				{
					warning.push (' ++ ' + names[ times[y] ] + ' is later than ' + names [ times[x] ]); 	
				}
			}
		}
		
		return {
			errors 		: error,
			warnings 	: warning
		};
	}
	
	this.commit = function ()
	{ 
		var validation 	= this.validate ();
		var error 		= validation.errors;
		var warning 	= validation.warnings;
		
		if (error.length > 0)
		{
			alert ("<b>Unable to save '" + this.EventName + "' because errors were found validating the event:</b>" + 
				   "<hr noshade size=1><font color=firebrick>" + 
				   error.join ("<br>") + 
				   "</font>");
			return true;
		}
		
		if (warning.length > 0)
		{
			if (!confirm ('Encountered warnings:\n' + warning.join ('\n') + '\nYou can proceed but there may be problems. Continue?') )
			{
				return true;
			}
		}
		// dialog ( this.Serialize () );
		this.cancel ();
        var RequestParams = {  
            'aftersend' : AfterSave ,
            'message' : 'Receiving save response...',
            'method' : 'POST',
            'postdata' : this.Serialize ()
                  }; 
        window.request.create (RequestParams);  
	}
	
	this.save = function ()
	{ 
		if (this.ConflictError==2) this.commit();
		else if (this.ConflictError==1) alert ('Please clear any conflicts before continuing'); 
		else this.verifyex (function () { AfterVerify( function () { window.currentevent.afterpresave(); }); });
	}
	
	this.verify = function ()
	{
		this.verifyex (AfterVerify);
	}
	
	this.verifyex = function (callback)
	{
		var n, v, request;
		this.ConflictError=0;
		var postdata = '<verify>';
		postdata += this.SerializeFields();  
		postdata += this.SerializeDate();
		postdata += this.SerializeRoom(); 
		postdata += '</verify>';  
		
		//if (confirm('Would  you like to see the request before I send it?'))
		//{var xx=window.open();xx.document.write ('<xmp>'+postdata+'</xmp>');}
		
		Controller.ConflictDates = [];
		window.currentevent.Conflicts = [];
        var RequestParams = {  
            'target' : window.currentevent.Conflicts ,
            'aftersend' : callback ,
            'serializer' : function (target, data) 
			{ 
				//for (var e in data) alert (e+'-->'+data[e]);
				if (data['ID']&&data['ID']!=window.currentevent.ID) target.push(data); 
			} ,
            'message' : 'Receiving conflict response...',
            'method' : 'POST',
            'postdata' : postdata
                  }; 
        window.request.create (RequestParams); 
	}   
	
	this.Serialize = function ()
	{ 
		var markup='',clone_data='';
		if (this.cloneid && this.cloneid.length > 0)
		{
			clone_data = ' cloneid="' + this.cloneid + '" clonedate="' + this.clonedate + '"';
		}
		markup += '<event'+clone_data+'>\n'; 
		markup += this.SerializeFields();
		markup += this.SerializeCalendar();
		markup += this.SerializeCategory();
		markup += this.SerializeRoom();
		markup += this.SerializeComment();
		markup += this.SerializeProperty();
		markup += this.SerializeDate();
		markup += '</event>\n';
		return markup;
	} 
	
	//event/field
	this.SerializeFields = function ()
	{ 
		var markup='';  
		markup += this.cdata ('ID', this.ID);
        markup += this.cdata ('EventName', this.EventName);
        markup += this.cdata ('Featured', this.Featured);
        markup += this.cdata ('ApproveLogin', this.ApproveLogin);
        markup += this.cdata ('CreateLogin', this.CreateLogin);
        markup += this.cdata ('EventStartTime', this.EventStartTime);
        markup += this.cdata ('EventEndTime', this.EventEndTime);
        markup += this.cdata ('SetupStartTime', this.SetupStartTime);
        markup += this.cdata ('SetupEndTime', this.SetupEndTime);
        markup += this.cdata ('EventDate', this.EventDate);
        markup += this.cdata ('RecurseEndDate', this.RecurseEndDate);
        markup += this.cdata ('Attendees', this.Attendees);
        markup += this.cdata ('RecurseUnit', this.RecurseUnit);
        markup += this.cdata ('type', this.RecurseType);
        markup += this.cdata ('Description', this.Description);
        markup += this.cdata ('Comments', this.Comments);
		return markup;
	} 
	
	this.toXml = function (collection, object)
	{
		var markup='';
		markup+='      <record>\n'; 
		for (var x in object)
		{
		    markup += this.cdata (x, collection[ object[x] ]);
		} 
		markup+='      </record>\n'; 
		return markup;
	}
	
 
	//event/calendar/recordset/record/field[@name="Calendar"]
	this.SerializeCalendar = function ()
	{  
		if (this.EventCalendars.length==0) return '';
		var shell=this.SerializeEnvelope ('calendar');
		var markup=''; 
		for (var x in this.EventCalendars)
		{
		    markup += this.toXml (this.EventCalendars[x], { 'Calendar' : 'id' });
		} 
		markup = shell.replace ('[CONTENT]', markup);
		return markup;
	}
 
	//event/dates/recordset/record/field[@name="CustomDate"] 
	this.SerializeDate = function ()
	{  
		if (this.CustomDates.length==0) return '';
		var shell=this.SerializeEnvelope ('dates');
		var markup=''; 
		for (var x in this.CustomDates)
		{
		    markup += this.toXml (this.CustomDates[x], { 'CustomDate' : 'value' });
		} 
		markup = shell.replace ('[CONTENT]', markup);
		return markup;
	}
 
	//event/property/recordset/record
	this.SerializeProperty = function ()
	{  
		if (this.CustomProperties.length==0) return '';
		var shell=this.SerializeEnvelope ('property');
		var markup=''; 
		for (var x in this.CustomProperties)
		{
		    markup += this.toXml (this.CustomProperties[x], { 'propname' : 'name', 'propvalue' : 'value' });
		} 
		markup = shell.replace ('[CONTENT]', markup);
		return markup;
	}
 
	//event/comment/recordset/record
	this.SerializeComment = function ()
	{  
		if (this.EventComments.length==0) return '';
		var shell=this.SerializeEnvelope ('comment');
		var markup=''; 
		for (var x in this.EventComments)
		{
		    markup += this.toXml (this.EventComments[x], { 'CommentText' : 'CommentText', 'UserID' : 'UserID', 'id' : 'id' });
		} 
		markup = shell.replace ('[CONTENT]', markup);
		return markup;
	}
	
	//event/category/recordset/record/field *
	this.SerializeCategory = function ()
	{  
		if (this.EventCategories.length==0) return '';
		var shell=this.SerializeEnvelope ('category');
		var markup=''; 
		for (var x in this.EventCategories)
		{
		    markup += this.toXml (this.EventCategories[x], { 'id' : 'id' });
		} 
		markup = shell.replace ('[CONTENT]', markup);
		return markup;
	}
	
	//event/rooms/recordset/record/field * 
	this.SerializeRoom = function ()
	{  
		if (this.Rooms.length==0) return '';
		var shell=this.SerializeEnvelope ('rooms');
		var markup=''; 
		for (var rm in this.Rooms)
		{
		    markup += this.toXml (this.Rooms[rm], { 'value' : 'value' });
		} 
		markup = shell.replace ('[CONTENT]', markup);
		return markup;
	}
	registerTemplate  ('cdata', '<field name="(name)"><![CDATA[(value)]]></field>\n');
	
 }
 
 function EventCalendarObject (data)
 {
	 return {
		 id 		: data['Calendar'],
		 EventFk 	: data['EventFk']
	 } 
 }
 
 function EventComment (data)
 {
	 this.id= null;
	 this.UserID= null;
	 this.CommentDate= null;
	 this.CommentText= null;
	 this.EventFK= null;
	 this.FullName= null;
	 if (data)
	 {
		 this.id=data['id'];
		 this.UserID=data['UserID'];
		 this.CommentDate=data['CommentDate'];
		 this.CommentText=data['CommentText'];
		 this.EventFK=data['EventFK'];
		 this.FullName=data['FullName'];
	 }
 }
 
 function EventCategory (data)
 {
	 this.id = null;
	 this.title = null;
	 if (data)
	 {
		 this.id=data['id'];
		 this.title=data['title'];
	 }
 }
 
EventObject.empty = function (clone)
{
	var def_event_row=[];
	def_event_row["EventCount"]			="";
	def_event_row["EventName"]			="New Event";
	def_event_row["RoomName"]			="Please choose a room";
	def_event_row["SetupStartTime"]		="12:00:00";
	def_event_row["SetupEndTime"]		="12:00:00";
	def_event_row["EventStartTime"]		="12:00:00";
	def_event_row["EventEndTime"]		="12:00:00";
	def_event_row["EventDate"]			= dateUK ();
	def_event_row["RecurseEndDate"]		=null;
	def_event_row["Duration"]			="0";
	def_event_row["FullName"]			=window.loggedinuser.name + ' ' + window.loggedinuser.last;
	def_event_row["Description"]		="";
	def_event_row["Comments"]			="Enter any comments here";
	def_event_row["CreateDate"]			= dateUK ();
	def_event_row["CreateLogin"]		=window.loggedinuser.id;
	def_event_row["ApproveDate"]		= dateUK ();
	def_event_row["ApproveLogin"]		=window.loggedinuser.id;
	def_event_row["Display"]			=0;
	def_event_row["Recurring"]			=0;
	def_event_row["Attendees"]			=0;
	def_event_row["RecurseType"]		=-1;
	def_event_row["RecurseUnit"]		=1;
	def_event_row["CustomDate"]			=null;
	def_event_row["type"]				=-1;
	def_event_row["RoomIdent"]			=0;
	def_event_row["ID"]					=0;
	def_event_row["RoomID"]				=0;
	def_event_row["Featured"]			=0; 
	if (clone) { for (var x in clone) def_event_row[x]=clone[x]; }
	return def_event_row;
} 
 
 
EventObject.params = function ()
{
	var def_event_row=[];
	def_event_row["EventName"]			="Event Name";
	def_event_row["RoomName"]			="Room Name";
	def_event_row["EventDate"]			="Event Date";
	def_event_row["RecurseEndDate"]		="End Date"; 
	def_event_row["SetupStartTime"]		="Setup Start Time";
	def_event_row["SetupEndTime"]		="Setup End Time"; 
	def_event_row["EventStartTime"]		="Event Start Time";
	def_event_row["EventEndTime"]		="Event End Time";
	def_event_row["Duration"]			="Duration";
	def_event_row["Comments"]			="Set up"; 
	def_event_row["Comments"]		    ="Description";
//	def_event_row["Comments"]		    ="Comments";
	def_event_row["FullName"]			="Creator";
	def_event_row["CreateDate"]			="Create Date";
	def_event_row["ApproveLogin"]		="Approver";
	def_event_row["ApproveDate"]		="Approve Date";
	def_event_row["Attendees"]			="Attendees";
	def_event_row["CustomDate"]			="Date Pattern"; 
	return def_event_row;
}
 
 
 
EventObject.params.pos = function (x)
{
	var i=0,pt=EventObject.params();
	for (var e in pt)
	{
		if (e==x) return Math.pow(2, i);
		i ++;
	}
} 
 
 
 function CustomDate (t,v)
 {
	 this.title=t;
	 this.value=v;
 }
 
function AddorRemoveCalendar(index, selected)
{
	//var d=[];for (var x in window.calendars[index]) d.push (x + ': ' + window.calendars[index][x]); dialog (d.join ('\n'))
	if (selected) window.currentevent.AddCalendar (window.calendars[index]);
	else window.currentevent.RemoveCalendar (window.calendars[index]['id']); 
}

function AddorRemoveCategory (name, value, selected)
{ 
	if (selected) window.currentevent.AddCategory (name, value);
	else window.currentevent.RemoveCategory (value); 
} 

function AddorRemoveProperty (name, value, selected)
{ 
	if (selected) window.currentevent.AddProperty (name, value);
	else window.currentevent.RemoveProperty (name); 
} 

function MultiAddorRemoveProperty(name, dropdown)
{
    var values = new Array ();
    for (var x=0;x<dropdown.options.length;x++)
    {
        if (dropdown.options[x].selected) values.push (dropdown.options[x].text);
    }
    AddorRemoveProperty (name, values.join (','), values.length > 0);
}

function AfterVerify(callback)
{
	if (typeof(callback)=='function') return callback();
	else if (window.currentevent.Conflicts.length==0) return confirm ('No conflicts detected');
	else DebugEventDetailForm.invoke();
	//dialog (callback);
}

function AfterSave()
{
	if (window.http.readyState==ReadyState.DONE) 
	{
	//	dialog ( window.http.responseText );
		var re = /\{(\d+)\}/ ;
		var mm = re.exec (window.http.responseText);
		if (Controller.domClone) { /*do nothing*/ }
		else if (mm) window.currentevent.ID = parseInt(mm[1]); 
		Controller.domClone 	= null;
		Controller.single_edit 	= null;
        LoadEventDetailCustomProperties ();
	} 
}
 